﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractLcd;
using HamcoWcs.Contract.ContractMainTask;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.DeviceMsgQueues;
using HamcoWcs.Entitys.SubTasks;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.DeviceMsgQueues;
using HamcoWcs.Models.DeviceMsgs;
using HamcoWcs.Models.Devices;
using HamcoWcs.Models.TibcoMessage;
using HamcoWcs.Service.Common;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace HamcoWcs.Service.Pcon.PconPlcDbMsgParsers
{
    /// <summary>
    /// 请求目的地
    /// </summary>
    public class PconMsgParse_RequestDest : PconMsgParseBase
    {
        private readonly ILoggerService _loggerService;
        private readonly IBaseTaskService _baseTaskService;
        private readonly IPathService _pathService;
        private readonly IBaseMainTaskService _baseMainTaskService;
        private readonly ILcdService _lcdService;
        private readonly IMesBaseService _mesBaseService;
        private readonly AutomaticStorageInfo _asrs;

        public override EnumPconPlcRequest RequestType => EnumPconPlcRequest.RequestDest;

        public PconMsgParse_RequestDest(
             IMapper mapper, WcsDbContext wcsDbContext, ILoggerService loggerService,
            IBaseTaskService baseTaskService, IPathService pathService, IBaseMainTaskService baseMainTaskService
            , ILcdService lcdService,
            IMesBaseService mesBaseService,
            IMesCommunicateService mesCommunicateService,
            AutomaticStorageInfo asrs)
            : base(mesCommunicateService, wcsDbContext, mapper)
        {
            _loggerService = loggerService;
            _baseMainTaskService = baseMainTaskService;
            _pathService = pathService;
            _baseTaskService = baseTaskService;
            _lcdService = lcdService;
            _mesBaseService = mesBaseService;
            _asrs = asrs;
        }

        private static List<string> SPECIAL_NODES = new List<string>
        {
            "CJRGV100",
            "CJRGV200",
            "CJMIFB00",
            "CJMIFC00",
        };

        private SubTask GetNextSubTask(SubTask subTask)
        {
            var mainTask = _wcsDbContext.MainTasks
                .Where(x => x.Id == subTask.MainTask.Id)
                .Include(x => x.SubTasks)
                .FirstOrDefault();

            return mainTask.SubTasks[subTask.TaskSeq];
        }



        public override void Deal(PconDto pconDto, PconPlc pconPlc)
        {
            if (pconDto.UnitId == "")
            {
                _loggerService.AddWcsRunLog("device", $"{pconDto.DeviceName}请求目的地时未携带栈板号");
                return;
            }

            if (!pconDto.Machine.IsRunning)
            {
                _loggerService.AddWcsRunLog("device", $"{pconDto.DeviceName}请求目的地时状态不为RUN");
                return;
            }

            if (pconDto.IsGoods == 0)
            {
                _loggerService.AddWcsRunLog("device", $"{pconDto.DeviceName}请求目的地时无载荷");
                return;
            }

            if (pconDto.PconType == EnumPconType.InPortInteractive)
            {
                // 二楼实栈板入库交互
                _mesCommunicateService.PalletLocationChangedReport(
                    new PalletLocationChangedReportMessage(
                    new PalletLocationChangedReportMessageBody(pconDto.MachineName, pconDto.PortName, pconDto.UnitId, "IN")));
                Thread.Sleep(50);
                // 上报UR触发MES下发任务
                pconDto.PortState = "UR";
                _mesCommunicateService.PortTransferStateChanged(pconDto);
                return;
            }


            var taskEntity = _wcsDbContext.SubTasks
                              .AsQueryable()
                              .Where(x => x.UnitId == pconDto.UnitId)
                              .Where(x => x.TaskStatus == EnumSubTaskStatus.Ready.ToString()
                                       || x.TaskStatus == EnumSubTaskStatus.OnProgress.ToString())
                              .Where(x => x.FromLoc == pconDto.MachineName)
                              .Include(x => x.MainTask)
                              .Where(x => x.MainTask.TaskStatus == EnumMainTaskStatus.Ready.ToString()
                                       || x.MainTask.TaskStatus == EnumMainTaskStatus.OnProgress.ToString())
                              .FirstOrDefault();

            if (taskEntity == null) return;

            SubTask nextSubTask = null;
            string toNodeNmae = "";
            if (!SPECIAL_NODES.Contains(taskEntity.ToLoc))
            {
                toNodeNmae = taskEntity.ToLoc;
            }
            else
            {
                nextSubTask = GetNextSubTask(taskEntity);
                toNodeNmae = nextSubTask.ToLoc;
            }

            var node = _asrs.Nodes.FirstOrDefault(x => x.NodeName == toNodeNmae);
            string toLoc = node.InName;


            if (!string.IsNullOrEmpty(toLoc))
            {
                var msg = PconSendMsg.CreateDestMsg((ushort)pconDto.PconName, ushort.Parse(toLoc), pconDto.UnitId);
                var deviceMsgQueueDto = new DeviceMsgQueueDto(pconDto, msg);
                var deviceMsgQueue = _mapper.Map<DeviceMsgQueue>(deviceMsgQueueDto);

                _wcsDbContext.DeviceMsgQueues.Add(deviceMsgQueue);
                _baseTaskService.UpdateSubTaskStatus(taskEntity.Id, EnumSubTaskStatus.OnProgress);
            }
            else
            {
                _loggerService.AddSystemErrorLog($"PconMsgParse->RequestDest:任务{taskEntity.MainTask.TaskId}下发任务异常，未获取到正确的目的地。");
            }

        }

    }
}
